package com.simple.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hankcs.hanlp.seg.Dijkstra.DijkstraSegment;
import com.hankcs.hanlp.seg.Segment;
import com.hankcs.hanlp.seg.common.Term;
import com.simple.mapper.nrmp.QuestionAfantiMapper;
import com.simple.search.QuestionSearchImp;
import com.simple.util.CompareTextUtil;
import com.simple.util.ImageUtil;
import com.simple.util.OCRAFanTiUtil;
import com.simple.util.OCRYouDaoUtil;
import com.simple.util.WordRegionUtil;
import com.simple.vo.AFanTi;
import com.simple.vo.SearchQuestionResult;
import com.simple.vo.WordRegionList;
import com.sun.org.apache.xml.internal.security.utils.Base64;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.awt.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;



/**
 * 有道OCR题目搜索服务
 * @author lub
 */
@Service
public class QuestionSearchServiceImp {
	
    private static String reg = "[\u4e00-\u9fa5]";
    
    private static Pattern pat = Pattern.compile(reg);
    
    private static Set<String> fuhaoSet = new HashSet<>();
    
    private static String[] fuhaoArray = {",", ".", ";", ":", "?", "，", "。", "：", "；", "？", "“", "”", "…", "、", "\n", "　", "!", "\r"};
    
    private static float similar = 0.8f;

	@Value("${ocrmark.imgPath}")
	private String imgPath;// = "D:\\2.OCR_TXT\\searchImage\\";
    
    static {
    	for(int i = 0; i < fuhaoArray.length; i++) {
        	fuhaoSet.add(fuhaoArray[i]);
    	}
    }

    @Autowired
    private QuestionAfantiMapper questionAfantiMapper;



	public List<JSONObject> searchQuestionByImage(String  fileName,File file) throws Exception {
		//String imageBase64 = getLocalFileBase64(fileName);
		String imageBase64 = null;
		if(null != fileName){
			imageBase64 = getLocalFileBase64(fileName);
		}else{
			imageBase64 = getImageStr(file);
		}
		return searchQuestionByImageForAfanTest(imageBase64);
	}


	public String getLocalFileBase64 (String fileName){
		String filePath = imgPath + fileName;
		String imageBase64 = getImageStr(new File(filePath));
		return imageBase64;
	}








	
    /**
     * 指读的题目，要从底部搜起，除了指读，其他不要调用
     * @param ocr 有道ocr返回的原始json数据
     * @return
     */
    public List<Long> searchQuestionIdsYoudaoOcrPoint(String ocr, int width, int height){
    	long time = System.currentTimeMillis();
    	List<Long> questionList = new ArrayList<>();
    	List<WordRegionList> wordRegionListArray = WordRegionUtil.handleOcr(ocr, width, height);
    	List<String> supposeTexts = new ArrayList<>();
    	int lastLength = 1;
    	int size = wordRegionListArray.size();
    	for(int i = 0; i < size; i++) {
    		WordRegionList wordRegionList = wordRegionListArray.get(i);
    		String text = handleOcr(ocr, wordRegionList);
    		String[] segs = text.split(" ");
    		int addLength = lastLength * 30 / 100;
    		if(addLength < 3) {
    			addLength = 3;
    		}
    		if(addLength > 8) {
    			addLength = 8;
    		}
    		if((i == size - 1) || (segs.length >= 5 && segs.length >= lastLength + addLength)) {
    			lastLength = segs.length;
        		supposeTexts.add(text);
    		}
    		if(supposeTexts.size() >= 4) {
    			break;
    		}
    	}
    	/*
    	final List<String> supposeTextsFinal;
    	if(supposeTexts.size() > 5) {
    		supposeTextsFinal = supposeTexts.subList(0, 5);
    	}
    	else {
    		supposeTextsFinal = supposeTexts;
    	}
    	if(!supposeTexts.isEmpty()) {
    		final JSONArray[] results = new JSONArray[supposeTexts.size()];
    		for(int i = 0; i < supposeTexts.size(); i++) {
    			final int index = i;
    			Thread thread = new Thread() {
    				public void run() {
    					try {
            				results[index] = QuestionSearch.searchText(supposeTextsFinal.get(index));
    					}
    					catch(Exception e) {
    						results[index] = new JSONArray();
    					}
    				}
    			};
    			thread.start();
    		}
    		String fullText = handleOcr(ocr, null);
    		JSONArray fullArray = QuestionSearch.searchText(fullText);
    		boolean unFinishFlag = true;
    		while(unFinishFlag) {
    			unFinishFlag = false;
    			for(int i = 0; i < results.length; i++) {
    				if(results[i] == null) {
    					unFinishFlag = true;
    				}
    			}
    			if(unFinishFlag) {
    				try {
    					Thread.sleep(20);
    				}
    				catch(Exception e) {
    					
    				}
    			}
    		}
    		List<JSONObject> idObjectList = new ArrayList<>();
    		int splitIndex = results.length;
    		int maxFirst = 4;
    		int maxSecond = 4;
    		if(results.length == 3 || results.length == 4) {
    			splitIndex = 2;
    			maxFirst = 2;
    			maxSecond = 2;
    		}
    		else if(results.length > 5) {
    			splitIndex = 3;
    			maxFirst = 2;
    			maxSecond = 2;
    		}
    		for(int k = 0; k < splitIndex; k++) {
    			JSONArray resultArray = results[k];
    			if(resultArray.size() > 0) {
    				List<JSONObject> tempList = new ArrayList<>();
    				for(int i = 0; i < resultArray.size(); i++) {
    					JSONObject indexObject = resultArray.getJSONObject(i).getJSONObject("_source");
    					long id = indexObject.getLong("id");
    					String text = indexObject.getString("text");
    					JSONObject jsonObject = new JSONObject();
    					jsonObject.put("id", id);
    					float score = CompareTextUtil.compare(supposeTextsFinal.get(k), text);
    					jsonObject.put("score", score);
    					tempList.add(jsonObject);
    				}
    				if(tempList.size() > maxFirst) {
    					tempList = tempList.subList(0, maxFirst);
    				}
        			idObjectList.addAll(tempList);
    			}
    		}
    		for(int k = splitIndex; k < results.length; k++) {
    			JSONArray resultArray = results[k];
    			if(resultArray.size() > 0) {
    				List<JSONObject> tempList = new ArrayList<>();
    				for(int i = 0; i < resultArray.size(); i++) {
    					JSONObject indexObject = resultArray.getJSONObject(i).getJSONObject("_source");
    					long id = indexObject.getLong("id");
    					String text = indexObject.getString("text");
    					JSONObject jsonObject = new JSONObject();
    					jsonObject.put("id", id);
    					float score = CompareTextUtil.compare(supposeTextsFinal.get(k), text);
    					jsonObject.put("score", score);
    					tempList.add(jsonObject);
    				}
    				if(tempList.size() > maxSecond) {
    					tempList = tempList.subList(0, maxSecond);
    				}
        			idObjectList.addAll(tempList);
    			}
    		}
    		List<JSONObject> tempList = new ArrayList<>();
    		for(int i = 0; i < fullArray.size(); i++) {
				JSONObject indexObject = fullArray.getJSONObject(i).getJSONObject("_source");
				long id = indexObject.getLong("id");
				String text = indexObject.getString("text");
				JSONObject jsonObject = new JSONObject();
				jsonObject.put("id", id);
				jsonObject.put("score", CompareTextUtil.compare(fullText, text));
				tempList.add(jsonObject);
				if(tempList.size() > 2) {
					tempList = tempList.subList(0, 2);
				}
    			idObjectList.addAll(tempList);
			}
    		sortByScore(idObjectList);
    		Set<Long> set = new HashSet<>();
    		for(JSONObject jsonObject: idObjectList) {
    			long id = jsonObject.getLongValue("id");
    			if(!set.contains(id)) {
        			questionList.add(id);
        			set.add(id);
        			if(questionList.size() >= 5) {
        				break;
        			}
    			}
    		}
    	}
    	*/
    	JSONArray resultArray = QuestionSearchImp.searchTextMulti(supposeTexts);
    	for(int i = 0; i < resultArray.size() && questionList.size() < 5; i++) {
			JSONObject indexObject = resultArray.getJSONObject(i).getJSONObject("_source");
			long id = indexObject.getLong("id");
			questionList.add(id);
		}
		System.out.println("soutiPointMill="+(System.currentTimeMillis() - time) + "ms");
		System.out.println(questionList);
		return questionList;
    }
    
    private void sortByScore(List<JSONObject> list) {
    	Collections.sort(list, new Comparator<JSONObject>() {
			@Override
			public int compare(JSONObject o1, JSONObject o2) {
				float score = o2.getFloatValue("score") - o1.getFloatValue("score");
				if(score > 0f) {
					return 1;
				}
				else if(score == 0f) {
					return 0;
				}
				else {
					return -1;
				}
			}
		});
    }
    
    /**
     * 根据有道ocr返回的原始json数据，和科目subjectId搜题， subjectId为0的时候为所有的科目，返回0-5题数据
     * @param ocr
     * @param subjectId
     * @return
     * @throws Exception
     */
	public List<Long> searchQuestionIdsYoudaoOcr(String ocr, long subjectId) {
		long time = System.currentTimeMillis();
		String result = handleOcr(ocr);
		List<Long> questionList = new ArrayList<>();
		if(result != null) {
			JSONArray resultArray = null;
			if(subjectId == 0) {
				resultArray = QuestionSearchImp.searchText(result);
			}
			else {
				resultArray = QuestionSearchImp.searchTextSubject(result, subjectId);
			}
			for(int i = 0; i < resultArray.size() && questionList.size() < 5; i++) {
				JSONObject indexObject = resultArray.getJSONObject(i).getJSONObject("_source");
				long id = indexObject.getLong("id");
				questionList.add(id);
			}
		}
		System.out.println("soutiMill="+(System.currentTimeMillis() - time) + "ms");
		return questionList;
	}
	
	/**
	 * 根据有道ocr返回的原始json数据，和阿凡题ocr返回的json数据，和科目subjectId搜题， subjectId为0的时候为所有的科目，返回0-5题数据
	 * @param ocr 有道ocr结果
	 * @param aFanTiOcr 阿凡题ocr结果
	 * @param subjectId 科目id
	 * @return
	 */
	public List<SearchQuestionResult> searchQuestionIdsYoudaoAFanOcr(String ocr, String aFanTiOcr, long subjectId) {
		long time = System.currentTimeMillis();
		String result = handleOcr(ocr);
		List<SearchQuestionResult> questionList = new ArrayList<>();
		System.out.println("afantiOcr="+aFanTiOcr);
		AFanTi aFanTi = handleAFanTiResult(aFanTiOcr);
		System.out.println("aFanTi==null-->"+(aFanTi==null));
		if(aFanTi != null && subjectId != 0) {
			if(subjectId != aFanTi.getSubjectId()) {
				aFanTi = null;
			}
		}
		if(result != null) {
			JSONArray resultArray = null;
			if(subjectId == 0) {
				resultArray = QuestionSearchImp.searchText(result);
			}
			else {
				resultArray = QuestionSearchImp.searchTextSubject(result, subjectId);
			}
			if(aFanTi != null) { //假如阿凡题的题目的科目跟搜出来的题目的大部分的科目id不同，那么就认为没有搜到。
				Map<Long, Integer> countMap = new LinkedHashMap<>();
				for(int i = 0; i < resultArray.size() && questionList.size() < 5; i++) {
					JSONObject indexObject = resultArray.getJSONObject(i).getJSONObject("_source");
					long questionSubjectId = indexObject.getLong("subjectId");
					Integer count = countMap.get(questionSubjectId);
					if(count == null) {
						count = 0;
					}
					count++;
					countMap.put(questionSubjectId, count);
				}
				int maxCount = 0;
				long maxSubjectId = 0;
				for(long key: countMap.keySet()) {
					if(countMap.get(key) > maxCount) {
						maxSubjectId = key;
						maxCount = countMap.get(key);
					}
				}
				if(maxSubjectId != 0 && maxSubjectId != aFanTi.getSubjectId()) {
					aFanTi = null;
				}
			}
			if(resultArray.size() > 0) {
				boolean addAfantiFlag = false;
				for(int i = 0; i < resultArray.size() && questionList.size() < 5; i++) {
					JSONObject indexObject = resultArray.getJSONObject(i).getJSONObject("_source");
					long id = indexObject.getLong("id");
					if (aFanTi != null && !addAfantiFlag) {
//						String trunkHtml = aFanTi.getTrunkHtml();
//						Document doc = Jsoup.parse(trunkHtml);
//						doc.body().children().get(0).prepend("<span style=\"color: red;\">(阿凡题)</span><br>");
//						trunkHtml = doc.html();
//						aFanTi.setTrunkHtml(trunkHtml);
						String text = indexObject.getString("text");
						float score = CompareTextUtil.compare(text, result);
						if(score < aFanTi.getSearchScore()) {
							boolean changeFlag = false; //是否我们自己的题优先
							if(i == 0) {
								if(isSimilar(text, aFanTi.getTrunkHtml(), 0.9f)) {
									changeFlag = true;
								}
							}
							if(changeFlag) {
								questionList.add(new SearchQuestionResult(id));
								questionList.add(new SearchQuestionResult(aFanTi));
							}
							else {
								questionList.add(new SearchQuestionResult(aFanTi));
								questionList.add(new SearchQuestionResult(id));
							}
							addAfantiFlag = true;
						}
						else {
							questionList.add(new SearchQuestionResult(id));
						}
					}
					else {
						questionList.add(new SearchQuestionResult(id));
					}
				}
				if(questionList.size() > 5) {
					questionList = questionList.subList(0, 5);
				}
				if(aFanTi != null && !addAfantiFlag && questionList.size() < 5) {
					questionList.add(new SearchQuestionResult(aFanTi));
				}
			}
			else if(aFanTi != null){
				questionList.add(new SearchQuestionResult(aFanTi));
			}
		}
		System.out.println("soutiMill="+(System.currentTimeMillis() - time) + "ms");
		return questionList;
	}

	private AFanTi handleAFanTiResult(String ocr) {
		try {
			JSONObject jsonObject = JSON.parseObject(ocr);
			if(jsonObject.getJSONObject("meta").getIntValue("status") != 0) {
				return null;
			}
			JSONObject result = jsonObject.getJSONObject("data").getJSONObject("search_result");
			if(result.getIntValue("is_figured_out") != 1) {
				return null;
			}
			AFanTi aFanTi = new AFanTi();
			aFanTi.setSubjectName(result.getString("subject"));
			// aFanTi.setKnowledgePointName(result.getString("knowledge_point"));
			String html = result.getString("answer_html_content");
			aFanTi.setTrunkHtml(OCRAFanTiUtil.getAFanTiTrunk(html));
			aFanTi.setAnalysHtml(OCRAFanTiUtil.getAFanTiAnalys(html));
			aFanTi.setAnswerHtml(OCRAFanTiUtil.getAFanTiAnswer(html));
			JSONObject infoObject = result.getJSONObject("unified_label");
			if(infoObject != null) {
				if(infoObject.containsKey("subject")) {
					aFanTi.setSubjectName(infoObject.getJSONObject("subject").getString("name"));
				}
				if(infoObject.containsKey("knowledge_point")) {
					aFanTi.parseKnowledge(infoObject.getJSONArray("knowledge_point"));
				}
			}
			String s = "window.question_id = \"";
			int questionIdStart = html.indexOf(s);
			if(questionIdStart == -1) {
				return null;
			}
			questionIdStart += s.length();
			int questionIdEnd = html.indexOf("\"", questionIdStart + 1);
			if(questionIdEnd == -1) {
				return null;
			}
			aFanTi.setQuestionId(Long.parseLong(html.substring(questionIdStart,questionIdEnd)));
			aFanTi.setOrigin(ocr);
			if(questionAfantiMapper.getById(aFanTi.getQuestionId()) == null) {
				try {
//					questionAfantiMapper.save(aFanTi);
				}
				catch(Exception e) {
					e.printStackTrace();
				}
			}
			else {
//				questionAfantiMapper.update(aFanTi);
			}
			if(result.containsKey("search_score")) {
				aFanTi.setSearchScore(result.getFloatValue("search_score"));
			}
			return aFanTi;
		}
		catch(Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
     * 根据文本，和科目subjectId搜题， subjectId为0的时候为所有的科目，返回0-5题数据
     * @param subjectId
     * @return
     * @throws Exception
     */
	public List<Long> searchQuestionIdsText(String text, long subjectId) {
		long time = System.currentTimeMillis();
		String result = handleText(text);
		List<Long> questionList = new ArrayList<>();
		if(result != null) {
			JSONArray resultArray = null;
			if(subjectId == 0) {
				resultArray = QuestionSearchImp.searchText(result);
			}
			else {
				resultArray = QuestionSearchImp.searchTextSubject(result, subjectId);
			}
			for(int i = 0; i < resultArray.size() && questionList.size() < 5; i++) {
				JSONObject indexObject = resultArray.getJSONObject(i).getJSONObject("_source");
				long id = indexObject.getLong("id");
				questionList.add(id);
			}
		}
		System.out.println("soutiMill="+(System.currentTimeMillis() - time) + "ms");
		return questionList;
	}

	/**
	 * 网页版测试搜索结果用，请不要调用
	 * @param cacheFile
	 */
	public List<JSONObject> searchQuestionByImageForTest(File cacheFile) throws Exception {
		String imageBase64 = getImageStr(cacheFile);
		String ocr = OCRYouDaoUtil.ocr(imageBase64);
		String result = handleOcr(ocr);
		List<JSONObject> questionList = new ArrayList<>();
		JSONObject originObject = new JSONObject();
		originObject.put("id", 0);
		originObject.put("trunk", "<img src=\"data:image/jpeg;base64," + getImageStr(cacheFile) + "\">");
		questionList.add(originObject);
		JSONObject searchObject = new JSONObject();
		searchObject.put("id", -1);
		searchObject.put("trunk", result);
		questionList.add(searchObject);
		if(result != null) {
			JSONArray resultArray = QuestionSearchImp.searchText(result);
			for(int i = 0; i < resultArray.size(); i++) {
				JSONObject questionObject = new JSONObject();
				JSONObject indexObject = resultArray.getJSONObject(i).getJSONObject("_source");
				questionObject.put("id", indexObject.getLong("id"));
				questionObject.put("trunk", indexObject.getString("text"));
				questionList.add(questionObject);
			}
		}
		return questionList;
	}
	
	/**
	 * 网页版测试搜索结果用，请不要调用
	 */
	public List<JSONObject> searchQuestionByImageForAfanTest(final String imageBase64) throws Exception {
		//final String imageBase64 = getImageStr(cacheFile);
		final String[] afanOcr = new String[1];
		Thread thread = new Thread() {
			public void run() {
				try {
					afanOcr[0] = OCRAFanTiUtil.ocr(imageBase64);
				}
				catch(Exception e) {
					afanOcr[0] = "error:" + e.getMessage();
				}
			}
		};
		thread.start();
		String ocr = OCRYouDaoUtil.ocr(imageBase64);
		while (afanOcr[0] == null) {
			Thread.sleep(100);
		}
		if(afanOcr[0].startsWith("error")) {
			throw new RuntimeException(afanOcr[0]);
		}
		String result = handleOcr(ocr);
		List<JSONObject> questionList = new ArrayList<>();
		JSONObject originObject = new JSONObject();
		originObject.put("id", 0);
		originObject.put("trunk", "<img src=\"data:image/jpeg;base64," + imageBase64 + "\" width=\"800\" height=\"300\">");
		questionList.add(originObject);
		JSONObject searchObject = new JSONObject();
		searchObject.put("id", -1);
		searchObject.put("trunk", result);
		questionList.add(searchObject);
		if(result != null) {
			List<SearchQuestionResult> resultList = searchQuestionIdsYoudaoAFanOcr(ocr,afanOcr[0] , 0);
			for(int i = 0; i < resultList.size(); i++) {
				JSONObject questionObject = new JSONObject();
				SearchQuestionResult questionResut = resultList.get(i);
				questionObject.put("type", questionResut.getType());
				if(questionResut.getType() == 0) {
					questionObject.put("id", questionResut.getQuestionId());
				}
				else {
					questionObject.put("trunk", questionResut.getaFanTi().getTrunkHtml());
					questionObject.put("analys", questionResut.getaFanTi().getAnalysHtml());
					questionObject.put("answer", questionResut.getaFanTi().getAnswerHtml());
				}
				questionList.add(questionObject);
			}
		}
		return questionList;
	}
	
	/**
	 * 网页版测试搜索结果用，请不要调用
	 * @param cacheFile
	 */
	public List<JSONObject> searchQuestionByImageForPointTest(File cacheFile) throws Exception {
		String imageBase64 = getImageStr(cacheFile);
		String ocr = OCRYouDaoUtil.ocr(imageBase64);
		Dimension dimension = null;
		if(imageBase64.startsWith("/9")) {
			dimension = ImageUtil.getJPGImageDimmension(Base64.decode(imageBase64));
		}
		else {
			dimension = ImageUtil.getPNGImageDimmension(Base64.decode(imageBase64));
		}
		List<WordRegionList> wordRegionListArray = WordRegionUtil.handleOcr(ocr,(int)dimension.getWidth(), (int)dimension.getHeight());
    	List<String> supposeTexts = new ArrayList<>();
    	for(WordRegionList wordRegionList: wordRegionListArray) {
    		String text = handleOcr(ocr, wordRegionList);
    		supposeTexts.add(text);
    	}
    	String result = supposeTexts.get(supposeTexts.size() - 1);
    	for(String text: supposeTexts) {
    		System.out.println(text);
    	}
		List<JSONObject> questionList = new ArrayList<>();
		JSONObject originObject = new JSONObject();
		originObject.put("id", 0);
		originObject.put("trunk", "<img src=\"data:image/jpeg;base64," + getImageStr(cacheFile) + "\">");
		questionList.add(originObject);
		JSONObject searchObject = new JSONObject();
		searchObject.put("id", -1);
		searchObject.put("trunk", result);
		questionList.add(searchObject);
		if(result != null) {
			JSONArray resultArray = QuestionSearchImp.searchTextMulti(supposeTexts);
			for(int i = 0; i < resultArray.size(); i++) {
				JSONObject questionObject = new JSONObject();
				JSONObject indexObject = resultArray.getJSONObject(i).getJSONObject("_source");
				questionObject.put("id", indexObject.getLong("id"));
				questionObject.put("trunk", indexObject.getString("text"));
				questionList.add(questionObject);
			}
		}
		return questionList;
	}
	
	/**
	 * 网页版测试搜索结果用，请不要调用
	 */
	public List<JSONObject> searchQuestionByTextForTest(String text) throws Exception {
		String handleText = handleText(text);
		List<JSONObject> questionList = new ArrayList<>();
		JSONObject searchObject = new JSONObject();
		searchObject.put("id", -1);
		searchObject.put("trunk", handleText);
		questionList.add(searchObject);
		JSONArray resultArray = QuestionSearchImp.searchText(handleText);
		for(int i = 0; i < resultArray.size(); i++) {
			JSONObject questionObject = new JSONObject();
			JSONObject indexObject = resultArray.getJSONObject(i).getJSONObject("_source");
			questionObject.put("id", indexObject.getLong("id"));
			questionObject.put("trunk", indexObject.getString("text"));
			questionList.add(questionObject);
		}
		return questionList;
	}
	
	private static String handleOcr(String ocr) {
		return handleOcr(ocr, null);
	}
	
	private static String handleOcr(String ocr, WordRegionList wordRegionList) {
		System.out.println(ocr);
		JSONObject ocrObject = JSON.parseObject(ocr);
		if(!ocrObject.getString("errorCode").equals("0")) {
			System.err.println(ocr);
			return null;
		}
		JSONArray regionArray = ocrObject.getJSONObject("Result").getJSONArray("regions");
		if (regionArray == null || regionArray.size() == 0) {
			return null;
		}
		int regionCount = regionArray.size();
		List<String> textList = new ArrayList<String>();
		for (int i = 0; i < regionCount; i++) { // 块
			StringBuffer textBuffer = new StringBuffer();
			JSONObject regionObj = (JSONObject)regionArray.get(i);
			JSONArray lineArray = regionObj.getJSONArray("lines");
			if (lineArray == null || lineArray.size() == 0) {
				continue;
			}
			int lineCount = lineArray.size();
			boolean lastIsChinese = false;
			for (int j = 0; j < lineCount; j++) { // 行
				JSONArray tmpArray = (JSONArray)lineArray.get(j);
				if (tmpArray == null || tmpArray.size() == 0) {
					continue;
				}
				for (int k = 0; k < tmpArray.size(); k++) {
					JSONObject obj = tmpArray.getJSONObject(k);
					if(wordRegionList == null || wordRegionList.getRegionMap().containsKey(obj.getString("boundingBox"))) {
						String text = obj.getString("text");
						String type = obj.getString("type");
						if (type.equals("formula")) {
							text = text.replaceAll("si\\s*([\\\\^{])", "sin$1")
									.replaceAll("co\\s*([\\\\^{])", "cos$1")
									.replaceAll("\\{}", " ")
									.trim();
							while (text.endsWith("{")) {
								text = text.substring(0, text.length() - 1).trim();
							}
							textBuffer.append(" "+ text+" ");
							lastIsChinese = false;
						}
						else {
							if(k == 0) {
								if(lastIsChinese && text.length() > 0) {
									lastIsChinese = false;
									String word = text.substring(0, 1);
									if(containChinese(word)) {
										textBuffer.append(text);
									}
									else {
										textBuffer.append(" "+text);
									}
								}
								else {
									textBuffer.append(" "+text);
								}
							}
							else {
								textBuffer.append(text);
							}
						}
					}
				}
				lastIsChinese = false;
				if(textBuffer.length() > 0) {
					String word = textBuffer.substring(textBuffer.length() - 1);
					if(containChinese(word)) {
						lastIsChinese = true;
					}
				}
			}
			if(textBuffer.length() > 0) {
				String text = textBuffer.toString();
				text = text.replace("÷", " ÷ ");
				text = text.replace("^ { \\prime }", "'");
				text = text.replace("^ { \\prime \\prime }", "\"");
				text = text.replace("\\prime", " ' ");
				text = text.replace("\\angle", " ∠ ");
				text = text.replace("\\triangle", " △ ");
				text = text.replace("\\Delta", " △ ");
				text = text.replace("\\pm", " ± ");
				text = text.replace("\\subseteq", " ≌ ");
				text = text.replace("\\odot", " ⊙ ");
				text = text.replace("\\approx", " ≈ ");
				text = text.replace("\\leq", " ≤ ");
				text = text.replace("\\geq", " ≥ ");
				text = text.replace("\\neq", " ≠ ");
				text = text.replace("\\perp", " ⊥ ");
				text = text.replace("\\bot", " ⊥ ");
				text = text.replace("\\cap", " ∩ ");
				text = text.replace("\\cup", " ∪ ");
				text = text.replace("\\}", "}");
				text = text.replace("\\{", "{");
				text = text.replace("∠", " ∠ ");
				
				if(text.contains(" \\alpha ")) {
					text = text.replace(" \\alpha ", " a");
				}
				text = text.replace("\\alpha", " a");
				if(text.contains(" \\beta ")) {
					text = text.replace(" \\beta ", " B");
				}
				text = text.replace("\\beta", " B");
				if(text.contains(" \\gamma ")) {
					text = text.replace(" \\gamma ", " y");
				}
				text = text.replace("\\gamma", " y");
				if(text.contains(" \\pi ")) {
					text = text.replace(" \\pi ", "π");
				}
				text = text.replace("\\pi", "π");
				text = text.replace("\\quad", "");
				text = text.replace("\\div", " ÷ ");
				text = text.replace("\\times", " x ");
				text = text.replace("\\circ", " ° ");
				text = text.replace("\\cdot", "");
				text = text.replace("\\log", "log");
				text = text.replace("\\tan", "tan");
				text = text.replace("\\sin", "sin");
				text = text.replace("\\cos", "cos");
				
				text = text.replace("\\infty", " ∞ ");
				text = text.replace("\\in", " ∈ ");
				text = text.replace("≈", " ≈ ");
				text = text.replace("=", " = ");
				text = text.replace("~", " - ");
				text = text.replace("-", " - ");
				text = text.replace("+", " + ");
				text = text.replace("(", " ( ");
				text = text.replace(")", " ) ");
				text = text.replace("<", " < ");
				text = text.replace(">", " > ");
				text = text.replace("[", " [ ");
				text = text.replace("]", " ] ");
				text = text.replace("|", " | ");
				text = text.replace("{", " { ");
				text = text.replace("}", " } ");
				text = text.replace("/", " / ");
				text = text.replace("°", " ° ");
				text = text.replace("/   /", " // ");
				text = text.replace("/  /", " // ");
				text = text.replace("/ /", " // ");
				text = text.replace("^", " ^ ");
				text = text.replace("_", " _ ");

				Pattern p = Pattern.compile("\\\\mathrm|\\\\mathbf");
		        Matcher m = p.matcher(text);  
		        while(m.find()) {
		        	int start = m.start();
		        	int middle = text.indexOf("{", start);
		        	int end = text.indexOf("}", start);
		        	if(end == -1) {
		        		end = text.length() - 1;
		        	}
		        	text = text.substring(0, start) + text.substring(middle + 1, end).replace("~", "") + text.substring(end + 1);
		        	m = p.matcher(text);
		        }
		        text = text.replace("A.", " ");
		        text = text.replace("B.", " ");
		        text = text.replace("C.", " ");
		        text = text.replace("D.", " ");
				textList.add(text);
			}
		}
		String returnText = "";
		for(String text: textList) {
			List<String> segList = getSegText(text);
			for(String s: segList) {
				returnText += " " + s;
			}
		}
		
		Pattern p = Pattern.compile("[0-9][\\+\\-x÷/][0-9]");
		StringBuffer buffer = new StringBuffer(returnText);
        Matcher m = p.matcher(buffer);  
        while(m.find()) {
        	buffer.replace(m.start()+1, m.end()-1, " "+buffer.substring(m.start()+1, m.end()-1)+" ");
        	m = p.matcher(buffer);
        }
        
        p = Pattern.compile("[^0-9][\\+\\-x÷/][0-9]");
        m = p.matcher(buffer);  
        while(m.find()) {
        	buffer.replace(m.start()+1, m.end()-1, " "+buffer.substring(m.start()+1, m.end()-1)+" ");
        	m = p.matcher(buffer);
        }
        
        p = Pattern.compile("[0-9][\\+\\-÷/][^0-9]");
        m = p.matcher(buffer);  
        while(m.find()) {
        	buffer.replace(m.start()+1, m.end()-1, " "+buffer.substring(m.start()+1, m.end()-1)+" ");
        	m = p.matcher(buffer);
        }
        returnText = buffer.toString();
		returnText = returnText.replace("      ", " ");
		returnText = returnText.replace("     ", " ");
		returnText = returnText.replace("    ", " ");
		returnText = returnText.replace("   ", " ");
		returnText = returnText.replace("  ", " ");
		returnText = returnText.replace("( )", "");
		returnText = returnText.replace("^ { ° }", " ° ");
		returnText = returnText.replace("sqrt { 3 } {", "sqrt [ 3 ] {");
		returnText = returnText.replace("sqrt { 4 } {", "sqrt [ 4 ] {");
		returnText = returnText.replace("sqrt { 5 } {", "sqrt [ 5 ] {");
		returnText = returnText.replace("点 0", "点 O");
		returnText = returnText.replace("圆 0", "圆 O");
		returnText = returnText.replace("  ", " ");
		String[] searchTextArray = returnText.split(" ");
		String searchTemp = returnText;
		if(searchTextArray.length > 250) {
			searchTemp = "";
			for(int i = 0; i < 250; i++) {
				searchTemp += " " + searchTextArray[i];
			}
			searchTemp = searchTemp.trim();
		}
		return handleDanwei(searchTemp);
	}

	private static String handleText(String text) {
		text = text.replace("÷", " ÷ ");
		text = text.replace("×", " x "); //乘号变成x
		text = text.replace("+", " + ");
		text = text.replace("-", " - ");
		text = text.replace("/", " / ");
		text = text.replace("−", " - ");
		text = text.replace("—", " - ");
		text = text.replace("=", " = ");
		text = text.replace("±", " ± ");
		text = text.replace("(", " ( ");
		text = text.replace(")", " ) ");
		text = text.replace("<", " < ");
		text = text.replace(">", " > ");
		text = text.replace("○", " ○ ");
		text = text.replace("[", " [ ");
		text = text.replace("]", " ] ");
		text = text.replace("|", " | ");
		text = text.replace("│", " | ");
		text = text.replace("·", " · ");
		text = text.replace("□", " □ ");
		text = text.replace("≈", " ≈ ");
		text = text.replace("~", " - ");
		text = text.replace("≤", " ≤ ");
		text = text.replace("≠", " ≠ ");
		text = text.replace("≥", " ≥ ");
		text = text.replace("≦", " ≤ ");
		text = text.replace("≧", " ≥ ");
		text = text.replace("°", " ° ");
		text = text.replace("′", " ' ");
		text = text.replace("″", " \" ");
		text = text.replace("∠", " ∠ ");
		text = text.replace("△", " △ ");
		text = text.replace("//", " // ");
		text = text.replace("/ /", " // ");
		text = text.replace("/  /", " // ");
		text = text.replace("/   /", " // ");
		text = text.replace("∥", " // ");
		text = text.replace("‖", " // ");
		text = text.replace("⊥", " ⊥ ");
		text = text.replace("≌", " ≌ ");
		text = text.replace("⊙", " ⊙ ");
		text = text.replace("•", " • ");
		text = text.replace("→", " → ");
		text = text.replace("⇌", " ⇌ ");
		text = text.replace("↑", " ↑ ");
		text = text.replace("☉", " ☉ "); 
		text = text.replace("∈", " ∈ ");
		text = text.replace("∞", " ∞ ");
		String returnText = "";
		List<String> segList = getSegText(text);
		int count = 0;
		for(String s: segList) {
			count++;
			returnText += " " + s;
			if(count >= 250) {
				break;
			}
		}
		return handleDanwei(returnText.trim());
	}
	
	private static List<String> getSegText(String text){
		List<String> textList = new ArrayList<>();
		char[] charList = text.toCharArray();
		StringBuilder buffer = new StringBuilder();
		boolean hanziFlag = true;
		Segment nShortSegment = new DijkstraSegment().enableCustomDictionary(false).enableAllNamedEntityRecognize(true);
		for(char c : charList) {
			if(buffer.length() == 0) {
				if(containChinese(c+"")) {
					hanziFlag = true;
					buffer.append(c);
				}
				else if(fuhaoSet.contains(c+"")) {
					
				}
				else {
					hanziFlag = false;
					buffer.append(c);
				}
			}
			else {
				if(containChinese(c+"")) {
					if(hanziFlag) {
						buffer.append(c);
					}
					else {
						String notHanzi = buffer.toString();
						textList.add(notHanzi);
						buffer = new StringBuilder();
						buffer.append(c);
						hanziFlag = true;
					}
				}
				else if(fuhaoSet.contains(c+"")) {
					if(hanziFlag) {
						String hanzi = buffer.toString();
						List<Term> termList = nShortSegment.seg(hanzi);
						String s = "";
						for(Term term: termList) {
							s += " " + term.word;
						}
						textList.add(s.trim());
					}
					else {
						String notHanzi = buffer.toString();
						textList.add(notHanzi);
					}
					buffer = new StringBuilder();
				}
				else {
					if(hanziFlag) {
						String hanzi = buffer.toString();
						List<Term> termList = nShortSegment.seg(hanzi);
						String s = "";
						for(Term term: termList) {
							s += " " + term.word;
						}
						textList.add(s.trim());
						buffer = new StringBuilder();
						buffer.append(c);
						hanziFlag = false;
					}
					else {
						buffer.append(c);
					}
				}
			}
		}
		if(buffer.length() > 0) {
			if(hanziFlag) {
				String hanzi = buffer.toString();
				List<Term> termList = nShortSegment.seg(hanzi);
				String s = "";
				for(Term term: termList) {
					s += " " + term.word;
				}
				textList.add(s.trim());
			}
			else {
				String notHanzi = buffer.toString();
				textList.add(notHanzi);
			}
		}
		return textList;
	}
	
	private static String handleDanwei(String text) {
		Pattern p = Pattern.compile("\\d\\s+(mm|cm|dm|m|km|KM|mg|Mg|g|kg|Kg|KG|m/s|kg/m|N|Pa|J|W|V)\\s+");
        Matcher m = p.matcher(text);  
        while(m.find()) {
        	int start = m.start();
        	text = text.substring(0, start + 1) + text.substring(start + 2);
        	m = p.matcher(text);
        }
        return text;
	}
	
	private static boolean containChinese(String s) {
		Matcher m = pat.matcher(s);
		return m.find();
	}
	
	/**
	 * 获得图片的Base64编码
	 * @param imgFile
	 * @return
	 */
	private static String getImageStr(File imgFile) {// 将图片文件转化为字节数组字符串，并对其进行Base64编码处理
		InputStream in = null;
		byte[] data = null;
		// 读取图片字节数组
		try {
			in = new FileInputStream(imgFile);
			data = new byte[in.available()];
			in.read(data);
		}
		catch (IOException e) {
			e.printStackTrace();
		}
		finally {
			if(in != null) {
				try {
					in.close();
				}
				catch(Exception e) {
					
				}
			}
		}
		// 对字节数组Base64编码
		return Base64.encode(data);
	}
	
	private static List<JSONObject> removeRepeat(List<JSONObject> srcList, int remainSize) {
		List<JSONObject> returnList = new ArrayList<>(remainSize);
		Set<String> set = new HashSet<>();
		for(int i = 0; i < srcList.size() && returnList.size() < remainSize; i++) {
			JSONObject questionObject = srcList.get(i);
			String md5 = questionObject.getString("md5");
			if(!set.contains(md5)) {
				set.add(md5);
				returnList.add(questionObject);
				questionObject.remove("md5");
				questionObject.remove("score");
			}
		}
		return returnList;
	}
	
	private boolean isSimilar(String text, String trunkHtml, float compareScore) {
		Document doc = Jsoup.parse(trunkHtml);
		String trunkText = doc.body().text();
		String spitText1 = getSplitText(text);
		String splitText2 = getSplitText(trunkText);
		float score = CompareTextUtil.compare(spitText1, splitText2);
		if(score >= compareScore) {
			return true;
		}
		char[] chineseChars1 = getChineseChars(text);
		char[] chineseChars2 = getChineseChars(trunkText);
		if(chineseChars1.length > 12 || chineseChars2.length > 12) {
			score = CompareTextUtil.compare(chineseChars1, chineseChars2);
		}
		return score >= compareScore;
	}
	
	private char[] getChineseChars(String text) {
		char[] chars = text.toCharArray();
		StringBuilder buffer = new StringBuilder();
		for(char c: chars) {
			if(c >= 0x4e00 && c <= 0x9fa5) {
				buffer.append(c);
			}
		}
		return buffer.toString().toCharArray();
	}
	
	private String getSplitText(String text) {
        if(text == null) {
            return "";
        }
        text = text.trim();
        List<String> singleList = new ArrayList<>();
        char[] chars = text.toCharArray();
        boolean letterFlag = false;
        String word = "";
        for(char c: chars) {
        	letterFlag = false;
            if(c >= 0x4e00 && c <= 0x9fa5) {
                singleList.add(""+c);
            }
            else if((c >= 65 && c <= 90) || (c >= 97 && c <= 122)) {
            	letterFlag = true;
            }
            if(letterFlag) {
            	word += c;
            }
            else if(word.length() > 0) {
            	if(!word.equals("frac")) {
                	singleList.add(word);
            	}
            	word = "";
            }
        }
        if(word.length() > 0 && !word.equals("frac")) {
        	singleList.add(word);
        }
        String returnString = "";
        for(String s: singleList) {
            returnString += " " + s;
        }
        return returnString.trim();
    }
}
